home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_std / array2.e < prev    next >
Text File  |  2000-03-25  |  12KB  |  424 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. class ARRAY2[E]
  13.    --
  14.    -- General prurpose, resizable, two dimensional array.
  15.    --
  16.  
  17. inherit COLLECTION2[E];
  18.    
  19. creation 
  20.    make, copy, from_collection2, from_collection, from_model
  21.  
  22. feature 
  23.    
  24.    lower1, lower2, upper1, upper2: INTEGER;
  25.    
  26. feature {ARRAY2}
  27.    
  28.    storage: NATIVE_ARRAY[E];
  29.          -- To store elements line by line.
  30.    
  31.    capacity: INTEGER;
  32.          -- Number of elements in `storage'.
  33.    
  34. feature -- Creation / modification :
  35.    
  36.    make(line_min, line_max, column_min, column_max: INTEGER) is
  37.          -- Reset all bounds `line_minimum' / `line_maximum' / `column_minimum' and
  38.          -- `column_maximum' using arguments as new values.
  39.          -- All elements are set to the default value of type E.
  40.       require
  41.          line_min <= line_max;
  42.          column_min <= column_max
  43.       do
  44.          lower1 := line_min;
  45.          upper1 := line_max;
  46.          lower2 := column_min;
  47.          upper2 := column_max;
  48.          if capacity >= count then
  49.             storage.clear_all(count - 1);
  50.          else
  51.             capacity := count;
  52.             storage := storage.calloc(count);
  53.          end;
  54.       ensure
  55.          line_minimum = line_min;
  56.          line_maximum = line_max;
  57.          column_minimum = column_min;
  58.          column_maximum = column_max;
  59.       end;
  60.    
  61.    from_collection2(model: COLLECTION2[like item]) is
  62.       local
  63.          i, j: INTEGER;
  64.       do
  65.          make(model.line_minimum,
  66.               model.line_maximum,
  67.               model.column_minimum,
  68.               model.column_maximum);
  69.          from
  70.             i := line_minimum;
  71.          until
  72.             i > line_maximum
  73.          loop
  74.             from
  75.                j := column_minimum;
  76.             until
  77.                j > column_maximum
  78.             loop
  79.                put(model.item(i,j),i,j);
  80.                j := j + 1;
  81.             end;
  82.             i := i + 1;
  83.          end;
  84.       ensure then
  85.          lower1 = model.lower1;
  86.          lower2 = model.lower2
  87.       end;
  88.    
  89.    from_collection(contents: COLLECTION[E];
  90.                    line_min, line_max, column_min, column_max: INTEGER) is
  91.          --  Reset all bounds using `line_min', `line_max', `column_min',
  92.          --  and `column_max' .
  93.          --  Copy all elements of `contents', line by line into Current.
  94.       require
  95.          line_min <= line_max;
  96.          column_min <= column_max;      
  97.          contents.count = (line_max - line_min + 1) * (column_max - column_min +1)
  98.       local
  99.          i: INTEGER 
  100.       do
  101.          make(line_min,line_max,column_min,column_max)
  102.          from 
  103.             i := 0  
  104.          until
  105.             i >= count
  106.          loop
  107.             storage.put(contents.item(contents.lower + i),i);
  108.             i := i + 1; 
  109.          end
  110.       ensure
  111.          line_minimum = line_min;
  112.          line_maximum = line_max;
  113.          column_minimum = column_min;
  114.          column_maximum = column_max;
  115.          count = contents.count
  116.       end
  117.  
  118.    from_model(model: COLLECTION[COLLECTION[E]]) is
  119.          -- The `model' is used to fill line by line the COLLECTION2.
  120.          -- Assume all sub-collections of `model' have the same indexing.
  121.       local
  122.          line, column: INTEGER;
  123.       do
  124.          make(model.lower,
  125.               model.upper,
  126.               model.first.lower,
  127.               model.first.upper);
  128.          from
  129.             line := model.lower;
  130.          until
  131.             line > model.upper
  132.          loop
  133.             from
  134.                column := model.first.lower
  135.             until
  136.                column > model.first.upper
  137.             loop
  138.                put(model.item(line).item(column),line,column);
  139.                column := column + 1;
  140.             end;
  141.             line := line + 1;
  142.          end;
  143.       ensure
  144.          line_minimum = model.lower;
  145.          line_maximum = model.upper;
  146.          column_minimum = model.first.lower;
  147.          column_maximum = model.first.upper
  148.       end;
  149.    
  150. feature -- Resizing :
  151.  
  152.    resize(line_min, line_max, column_min, column_max: INTEGER) is
  153.          -- Resize bounds of the Current array
  154.       require
  155.          line_max >= line_min;
  156.          column_max >= column_min;
  157.       local
  158.          tmp: like Current;
  159.          l, c: INTEGER;
  160.       do
  161.          !!tmp.make(line_min, line_max, column_min, column_max);
  162.          -- It may be possible to avoid this ceation when :
  163.          --    new `capacity' <= old `capacity'
  164.          from
  165.             l := lower1;
  166.          until
  167.             l > line_maximum
  168.          loop
  169.             from
  170.                c := lower2;
  171.             until
  172.                c > column_maximum
  173.             loop
  174.                if tmp.valid_index(l,c) then
  175.                   tmp.put(item(l,c),l,c);
  176.                end;
  177.                c := c + 1;
  178.             end;
  179.             l := l + 1;
  180.          end;
  181.          standard_copy(tmp);
  182.       ensure
  183.          line_minimum = line_min;
  184.          line_maximum = line_max;
  185.          column_minimum = column_min;
  186.          column_maximum = column_max;
  187.       end;
  188.    
  189. feature -- Implementation of others feature from COLLECTION2 :
  190.    
  191.    item(line, column: INTEGER): E is
  192.       do
  193.          Result := storage.item((line - lower1) * count2 + column - lower2);
  194.       end;
  195.  
  196.    put(element: like item; line, column: INTEGER) is
  197.       do
  198.          storage.put(element,(line - lower1) * count2 + column - lower2);
  199.       end;
  200.    
  201.    count1: INTEGER is
  202.       do
  203.          Result := upper1 - lower1 + 1;
  204.       end;
  205.    
  206.    count2: INTEGER is
  207.       do
  208.          Result := upper2 - lower2 + 1;
  209.       end;
  210.  
  211.    count: INTEGER is
  212.       do
  213.          Result := count1 * count2;
  214.       end;
  215.    
  216.    force(x: like item; line, column: INTEGER) is
  217.       require
  218.          true
  219.       do
  220.          if not valid_index(line,column) then
  221.             resize(line.min(lower1),
  222.                    line.max(upper1),
  223.                    column.min(lower2),
  224.                    column.max(upper2));
  225.          end;
  226.          put(x,line,column);
  227.       end;
  228.    
  229.    set_all_with(element: E) is
  230.       do
  231.          storage.set_all_with(element,count - 1);
  232.       end;
  233.    
  234.    replace_all(old_value, new_value: like item) is
  235.       do
  236.          storage.replace_all(old_value,new_value,count - 1);
  237.       end;
  238.          
  239.    fast_replace_all(old_value, new_value: like item) is
  240.       do
  241.          storage.fast_replace_all(old_value,new_value,count - 1);
  242.       end;
  243.          
  244.    sub_collection2(line_min, line_max, column_min, column_max: INTEGER): like Current is
  245.       require  
  246.          valid_index(line_min,line_max) 
  247.          valid_index(column_min,column_max)
  248.       local
  249.          i, j, k: INTEGER;
  250.       do
  251.          !!Result.make(line_min,line_max,column_min,column_max);
  252.          from
  253.             i := line_min;
  254.             k := 0;
  255.          until
  256.             i > line_max
  257.          loop
  258.             from
  259.                j := column_min;
  260.             until
  261.                j > column_max
  262.             loop
  263.                Result.storage.put(item(i,j),k);
  264.                j := j + 1;
  265.                k := k + 1;
  266.             end;
  267.             i := i + 1;
  268.          end;
  269.       ensure
  270.          Result.lower1 = line_min; 
  271.          Result.lower2 = column_min; 
  272.          Result.upper1 = line_max;
  273.          Result.upper2 = column_max;
  274.       end;
  275.  
  276. feature --  Looking and comparison :
  277.  
  278.    nb_occurrences(elt: E): INTEGER is
  279.          -- Number of occurrences using `equal'.
  280.          -- See also `fast_nb_occurrences' to chose
  281.          -- the apropriate one.
  282.       do
  283.          Result := storage.nb_occurrences(elt,count - 1);
  284.       ensure
  285.          Result >= 0;
  286.       end;
  287.    
  288.    fast_nb_occurrences(elt: E): INTEGER is
  289.          -- Number of occurrences using `='.
  290.       do
  291.          Result := storage.fast_nb_occurrences(elt,count - 1);
  292.       ensure
  293.          Result >= 0;
  294.       end;
  295.  
  296.    has(x: like item): BOOLEAN is
  297.          -- Search if a element x is in the array using `equal'.
  298.          -- See also `fast_has' to chose the apropriate one.
  299.       do
  300.          Result := storage.index_of(x,count - 1) <= count - 1;
  301.       end;
  302.    
  303.    fast_has(x: like item): BOOLEAN is
  304.          --  Search if a element x is in the array using `='.
  305.       do
  306.          Result := storage.fast_index_of(x,count - 1) <= count -1;
  307.       end;
  308.    
  309.    all_default: BOOLEAN is
  310.       do
  311.          result := storage.all_default(count - 1);
  312.       end;
  313.  
  314.    swap(line1, column1, line2, column2 : INTEGER) is
  315.       local
  316.          tmp: like item;
  317.          c2, index1, index2: INTEGER;
  318.       do
  319.          c2 := count2;
  320.          index1 := (line1 - lower1) * c2 + column1 - lower2;
  321.          index2 := (line2 - lower1) * c2 + column2 - lower2;
  322.          tmp := storage.item(index1);
  323.          storage.put(storage.item(index2),index1);
  324.          storage.put(tmp,index2);
  325.       end
  326.  
  327.    copy(other: like Current) is
  328.       do
  329.          lower1 := other.lower1;
  330.          upper1 := other.upper1;
  331.          lower2 := other.lower2;
  332.          upper2 := other.upper2;
  333.          if capacity < count then
  334.             capacity := count;
  335.             storage := storage.calloc(count);
  336.          end;
  337.          storage.copy_from(other.storage, count - 1);
  338.       end;
  339.    
  340.    is_equal(other: like Current): BOOLEAN is
  341.       do
  342.          if other = Current then
  343.             Result := true;
  344.          elseif lower1 /= other.lower1 then
  345.          elseif lower2 /= other.lower2 then
  346.          elseif upper1 /= other.upper1 then
  347.          elseif upper2 /= other.upper2 then
  348.          else
  349.             Result := storage.memcmp(other.storage,count);
  350.          end;
  351.       end;
  352.  
  353. feature -- Only for ARRAY2 :
  354.  
  355.    transpose is
  356.          -- Transpose the Current array
  357.       local
  358.          i,j : INTEGER;
  359.          oldu1,oldu2 : INTEGER;
  360.          oldl1,oldl2 : INTEGER;
  361.       do
  362.          oldu1 := line_maximum;
  363.          oldu2 := column_maximum;
  364.          oldl1 := lower1;
  365.          oldl2 := lower2;
  366.          resize(lower1.min(lower2),
  367.                 line_maximum.max(column_maximum),
  368.                 lower1.min(lower2),
  369.                 line_maximum.max(column_maximum));
  370.          from
  371.             i := lower1;
  372.          until 
  373.             i > line_maximum
  374.          loop
  375.             from 
  376.                j := i + 1;
  377.             until 
  378.                j > column_maximum
  379.             loop
  380.                swap(i,j,j,i);
  381.                j := j + 1;
  382.             end;
  383.             i := i + 1;
  384.          end;
  385.          resize(oldl2,oldu2,oldl1,oldu1);
  386.       ensure
  387.          line_minimum = old column_minimum; 
  388.          column_minimum = old line_minimum;
  389.          line_maximum = old column_maximum; 
  390.          column_maximum = old line_maximum;
  391.          count = old count;
  392.       end;
  393.  
  394.    to_external: POINTER is
  395.          -- Gives C access to the internal `storage' (may be dangerous).
  396.       do
  397.          Result := storage.to_external;
  398.       end;
  399.  
  400. feature {COLLECTION2}
  401.  
  402.    same_as(other: COLLECTION2[E]): BOOLEAN is
  403.       do
  404.          Result := other.same_as_array2(Current);
  405.       end;
  406.  
  407.    same_as_array2(other: ARRAY2[E]): BOOLEAN is
  408.       do
  409.          Result := standard_same_as(other);
  410.       end;
  411.  
  412.    same_as_fixed_array2(other: FIXED_ARRAY2[E]): BOOLEAN is
  413.       do
  414.          Result := standard_same_as(other);
  415.       end;
  416.  
  417. invariant
  418.  
  419.    count2 = upper2 - lower2 + 1;
  420.  
  421.    capacity >= count
  422.  
  423. end -- ARRAY2[E]
  424.